package com.seed.bpmn.provider.activiti.common.cmd;

import com.seed.bpmn.engine.common.constants.BpmnConstants;
import com.seed.bpmn.engine.common.util.Empty;
import com.seed.bpmn.engine.dto.ScheduleDTO;
import com.seed.bpmn.provider.activiti.common.util.DTOUtil;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ProcessDefinitionImpl;

import java.util.List;
import java.util.Map;

/**
 * 流程调度Command
 */
public class ScheduleCmd implements Command<ScheduleDTO> {

    /** 目标流程定义环节ID */
    private String activityId;

    /** 流程实例ID */
    private String processInstanceId;

    /** 跳转原因 */
    private String reason;

    /** 变量参数 候选人，候选组 */
    private Map<String, Object> variables;

    public ScheduleCmd(String processInstanceId, String activityId, Map<String, Object> variables) {
        this(processInstanceId, activityId, variables,"schedule");
    }

    public ScheduleCmd(String processInstanceId, String activityId, Map<String, Object> variables, String reason) {
        this.activityId = activityId;
        this.processInstanceId = processInstanceId;
        this.variables = variables;
        this.reason = reason;
    }

    @Override
    public ScheduleDTO execute(CommandContext commandContext) {
        ScheduleDTO s = new ScheduleDTO();
        try {
            ExecutionEntity executionEntity = commandContext.getExecutionEntityManager().findExecutionById(processInstanceId);

            //准备删除的待办任务
            List<TaskEntity> tasks = commandContext.getTaskEntityManager().findTasksByProcessInstanceId(processInstanceId);
            for(TaskEntity t : tasks){
              s.getCompleteTasks().add(DTOUtil.getTaskDTO(t));
            }

            //1. 删除当前execution的所有子execution
            //2. 删除当前execution下的所有task
            //3. 删除当前execution下的所有job
            executionEntity.destroyScope(reason);

            ProcessDefinitionImpl processDefinition = executionEntity.getProcessDefinition();
            ActivityImpl activity = processDefinition.findActivity(activityId);

            String multiInstance = (String) activity.getProperty(BpmnConstants.ATTRIBUTE_TASK_MULTIINSTANCE);
            String type = (String)activity.getProperty(BpmnConstants.ATTRIBUTE_TYPE);

            //当前执行实例
            ExecutionEntity currentExecutionEntity = executionEntity;

            if(BpmnConstants.ELEMENT_SUBPROCESS.equals(type) || Empty.isNotEmpty(multiInstance)){
                currentExecutionEntity = executionEntity.createExecution();
                executionEntity.setTransition(null);
                executionEntity.setActivity(null);
                executionEntity.setActive(false);
            }

            currentExecutionEntity.setVariables(this.variables);
            currentExecutionEntity.executeActivity(activity);

            s.setMessage("调度成功！");
            s.setSuccess(true);
        }catch (Exception e){
            s.setMessage("调度失败！"+e.getMessage());
            s.setSuccess(false);
        }
        return s;
    }

    public String getReason() {
        return reason;
    }

    public void setReason(String reason) {
        this.reason = reason;
    }
}
